pub use crate::reader::Reader;
use crate::{value::Value, Config};

#[derive(Debug)]
pub struct Function {
	pub args: Vec<Value>,
	pub ret: Value,
}
impl Function {
	pub fn from_str(src: &str) -> Option<Self> {
		Self::parse(&mut Reader::new(&src))
	}
	fn parse<'a>(r: &mut Reader<'a>) -> Option<Self> {
		r.consume_char('(').then_some(())?;
		let mut args = vec![];
		while let Some(next) = r.peek() {
			match next {
				')' => break,
				_ => args.push(Value::parse(r)?),
			}
		}
		r.consume_char(')').then_some(())?;
		let ret = Value::parse(r)?;
		Some(Self { args, ret })
	}
	pub fn fmt_argn_obj<'a>(&'a self, cfg: &'a Config) -> FmtArgnObj<'a> {
		FmtArgnObj(self, cfg)
	}
	pub fn fmt_argn_pass(&'_ self) -> FmtArgnPass<'_> {
		FmtArgnPass(self)
	}
}

pub struct FmtArgnObj<'a>(pub &'a Function, pub &'a Config);
impl<'a> std::fmt::Display for FmtArgnObj<'a> {
	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
		for (i, v) in self.0.args.iter().enumerate() {
			f.write_fmt(format_args!("arg{}:{},", i, v.fmt_jnim_type(false, self.1)))?;
		}
		Ok(())
	}
}
pub struct FmtArgnPass<'a>(pub &'a Function);
impl<'a> std::fmt::Display for FmtArgnPass<'a> {
	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
		for (i, _v) in self.0.args.iter().enumerate() {
			f.write_fmt(format_args!("arg{},", i))?;
		}
		Ok(())
	}
}
